using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Xml;
using Common.Utilities;
using Common.Utilities.Dispatcher;

namespace Workflows.Components
{
    /// <summary></summary>
    [Serializable]
    public abstract class WorkflowTriggerBase : WorkflowComponentBase
    {
        private WorkflowTriggerType _triggerType;
        private TimeLapseUnit _timeSpanUnit;
        private int _interval;
        private DateTime _firstStartTime;
        private DateTime _lastRunTime;
        private DateTime _nextRunTime;
        private bool _isActive;
        [Browsable(false), Category("Activity")]
        public override InstructionBase Instruction
        {
            get { return null;}
            set { }
        }

        //private GenericTriggerOutput _Output;
        //[Browsable(false), Category("Activity")]
        //public override ResultBase Output
        //{
        //    get
        //    {
        //        return this._Output;
        //    }
        //    set
        //    {
        //        this._Output = (GenericTriggerOutput) value;
        //    }
        //}

        #region ctor
        /// <summary></summary>
        public WorkflowTriggerBase()
            : base()
        {
            this.ComponentName = "Trigger";
            this.ComponentImage = Properties.Resources.DateTime;
            this.ComponentIcon = Properties.Resources.timer;
            this.ComponentActivityType = WorkflowActivityType.Trigger;
            this.ComponentCategory = WorkflowComponentCategory.Triggers.ToString();
            this.Description = "Trigger";

            this._triggerType = WorkflowTriggerType.TimerTrigger;
            this._timeSpanUnit = TimeLapseUnit.Day;
            this._interval = 1;
            this._lastRunTime=DateTime.MinValue;
            this._firstStartTime = DateTime.Now.AddMinutes(10);
            this._nextRunTime = DateTime.Now.AddDays(1);
            this._isActive = false;
            // this._Output=new GenericTriggerOutput(this.ComponentID,Guid.Empty,true);
        }
        #endregion

        #region props
        /// <summary></summary>
        [Browsable(true), Category("trigger")]
        public WorkflowTriggerType TriggerType
        {
            get
            {
                return this._triggerType;
            }
            set
            {
                this._triggerType = value;
            }
        }

        /// <summary></summary>
        [Browsable(true), Category("trigger")]
        public bool IsActive
        {
            get
            {
                return this._isActive;
            }
            set
            {
                this._isActive = value;
            }
        }

        /// <summary></summary>
        [Browsable(true), Category("trigger")]
        public TimeLapseUnit TimeSpanUnit
        {
            get
            {
                return this._timeSpanUnit;
            }
            set
            {
                this._timeSpanUnit = value;
            }
        }

        /// <summary></summary>
        [Browsable(true), Category("trigger")]
        public int Interval
        {
            get
            {
                return this._interval;
            }
            set
            {
                this._interval = value;
            }
        }

        /// <summary></summary>
        [Browsable(true), Category("trigger")]
        public DateTime StartTime
        {
            get
            {
                return this._firstStartTime;
            }
            set
            {
                this._firstStartTime = value;
            }
        }

        /// <summary></summary>
        [Browsable(true), Category("trigger")]
        public DateTime LastRunTime
        {
            get
            {
                return this._lastRunTime;
            }
            set
            {
                this._lastRunTime = value;
            }
        }

        /// <summary></summary>
        [Browsable(true), Category("trigger")]
        public DateTime NextRunTime
        {
            get
            {
                return this._nextRunTime;
            }
            set
            {
                this._nextRunTime = value;
            }
        }
        #endregion

        /// <summary></summary>
        public abstract ResultBase[] ProcessTrigger(DateTime lastRunTime);

        /// <summary></summary>
        public TimeSpan CreateTimeSpan()
        {
            switch (this.TimeSpanUnit)
            {
                case TimeLapseUnit.Day:
                    return new TimeSpan(this.Interval, 0, 0, 0);
                case TimeLapseUnit.Hour:
                    return new TimeSpan(this.Interval, 0, 0);
                case TimeLapseUnit.Minute:
                    return new TimeSpan(0, Interval, 0);
                case TimeLapseUnit.Month:
                    return new TimeSpan(30*Interval, 0, 0, 0);
                case TimeLapseUnit.Second:
                    return new TimeSpan(0, 0, Interval);
                case TimeLapseUnit.Week:
                    return new TimeSpan(Interval*7, 0, 0, 0);
                case TimeLapseUnit.Year:
                    return new TimeSpan(365*Interval, 0, 0, 0);
                default:
                    return new TimeSpan(0, Interval, 0);
            }
        }

        /// <summary></summary>
        public DateTime GetNextRunTime(DateTime lastRunTime)
        {
            DateTime nextRunTime = lastRunTime.Add(this.CreateTimeSpan());
            while (nextRunTime < DateTime.Now)
            {
                nextRunTime = nextRunTime.Add(this.CreateTimeSpan());
            }
            return nextRunTime;
        }
    }
}
